package com.kakarote.admin.controller;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.kakarote.core.common.enums.AdminRoleTypeEnum;
import com.kakarote.admin.entity.BO.AdminRoleBO;
import com.kakarote.admin.entity.BO.AdminUserRoleBO;
import com.kakarote.admin.entity.PO.AdminConfig;
import com.kakarote.admin.entity.PO.AdminRole;
import com.kakarote.admin.entity.VO.AdminRoleVO;
import com.kakarote.admin.service.IAdminConfigService;
import com.kakarote.admin.service.IAdminRoleAuthService;
import com.kakarote.admin.service.IAdminRoleService;
import com.kakarote.common.log.annotation.OperateLog;
import com.kakarote.common.log.entity.OperationLog;
import com.kakarote.common.log.entity.OperationResult;
import com.kakarote.common.log.enums.ApplyEnum;
import com.kakarote.common.log.enums.BehaviorEnum;
import com.kakarote.common.log.enums.OperateObjectEnum;
import com.kakarote.common.log.enums.OperateTypeEnum;
import com.kakarote.core.common.ApiExplain;
import com.kakarote.core.common.Result;
import com.kakarote.core.utils.UserUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 角色表 前端控制器
 * </p>
 *
 * @author zhangzhiwei
 * @since 2020-04-27
 */
@RestController
@RequestMapping("/adminRole")
@Api(tags = "角色模块")
public class AdminRoleController {
    @Autowired
    private IAdminRoleService adminRoleService;

    @Autowired
    private IAdminRoleAuthService adminRoleAuthService;

    @Autowired
    private IAdminConfigService configService;


    @PostMapping("/auth")
    @ApiOperation("角色权限")
    public Result<JSONObject> auth() {
        JSONObject object = adminRoleService.auth(UserUtil.getUserId());
        return Result.ok(object);
    }

    @PostMapping("/queryNoAuthMenu")
    @ApiOperation("获取未授权的菜单")
    public Result<List<String>> queryNoAuthMenu(@RequestParam("userId") @NotNull Long userId) {
        return Result.ok(adminRoleService.queryNoAuthMenu(userId));
    }

    @PostMapping("/getRoleList")
    @ApiOperation("查询新增员工时的可查询角色")
    public Result<List<AdminRoleVO>> getRoleList() {
        return Result.ok(adminRoleService.getRoleList());
    }

    @PostMapping("/getAllRoleList")
    @ApiOperation("全局角色查询")
    public Result<List<AdminRoleVO>> getAllRoleList() {
        List<AdminRoleVO> allRoleList = adminRoleService.getAllRoleList();
        return Result.ok(allRoleList);
    }

    @PostMapping("/getRoleTypeList")
    @ApiOperation("获取角色类型列表")
    public Result<List<Map<String, Object>>> getRoleTypeList() {
        List<Map<String, Object>> data = new ArrayList<>(7);
        data.add(new JSONObject().fluentPut("name", "系统管理角色").fluentPut("roleType", 1).fluentPut("languageKeyMap", new JSONObject().fluentPut("name_resourceKey", "menuRoles1.系统管理角色")));
        data.add(new JSONObject().fluentPut("name", "办公管理角色").fluentPut("roleType", 7).fluentPut("languageKeyMap", new JSONObject().fluentPut("name_resourceKey", "menuRoles7.办公管理角色")));
        List<AdminConfig> adminConfigs = configService.queryConfigListByName(AdminRoleTypeEnum.HRM.getName(), AdminRoleTypeEnum.FINANCE.getName(),
                AdminRoleTypeEnum.JXC.getName(), AdminRoleTypeEnum.SCRM.getName(), AdminRoleTypeEnum.CS.getName(), AdminRoleTypeEnum.WP.getName());
        Map<String, List<AdminConfig>> adminMap = adminConfigs.stream().collect(Collectors.groupingBy(AdminConfig::getName));
        if (adminMap.containsKey(AdminRoleTypeEnum.HRM.getName()) && adminMap.get(AdminRoleTypeEnum.HRM.getName()).get(0).getStatus() != 0) {
            data.add(new JSONObject().fluentPut("name", "人力资源管理角色").fluentPut("roleType", 9).fluentPut("languageKeyMap", new JSONObject().fluentPut("name_resourceKey", "menuRoles9.人力资源管理角色")));
        }
        return Result.ok(data);
    }

    @PostMapping("/getRoleByType/{type}")
    @ApiOperation("通过角色类型查询角色")
    public Result<List<AdminRole>> getRoleByType(@PathVariable("type") Integer type) {
        AdminRoleTypeEnum roleTypeEnum = AdminRoleTypeEnum.parse(type);
        List<AdminRole> roleByType = adminRoleService.getRoleByType(roleTypeEnum);
        return Result.ok(roleByType);
    }


    @PostMapping("/setSorting")
    @ApiOperation("角色排序")
    public Result setSorting(@RequestBody List<AdminRole> roleList) {

        List<AdminRole> list = new ArrayList<>();


        for (int i = 0; i < roleList.size(); i++) {
            AdminRole adminRole = roleList.get(i);
            AdminRole sort = new AdminRole();
            sort.setRoleId(adminRole.getRoleId());
            sort.setSorting(i);
            list.add(sort);
        }

        adminRoleService.updateBatchById(list);

        return Result.ok();
    }


    @PostMapping("/getAllRoleMenu")
    @ApiOperation("查询项目管理成员的权限")
    public Result<List<Long>> getAllRoleMenu(@RequestParam("roleIds") List<Long> roleIds) {
        List<AdminRole> adminRoles = null;
        List<Long> roles = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(roleIds)) {
            adminRoles = adminRoleService.lambdaQuery().in(AdminRole::getRoleId, roleIds).list();
        }
        List<AdminRole> roleByType = null;
        if (ObjectUtil.isNotEmpty(adminRoles)) {
            roleByType = adminRoleService.getAllRoleMenu(adminRoles);
            List<List<Long>> rules = roleByType.stream().map(r -> r.getRules().get("data")).collect(Collectors.toList());
            for (List<Long> list : rules) {
                roles.addAll(list);
            }
        }
        return Result.ok(roles);
    }

    @PostMapping("/getProjectRoleByType/{type}/{projectId}")
    @ApiOperation("项目管理:通过项目角色类型查询角色")
    public Result<List<AdminRole>> getProjectRoleByType(@PathVariable("type") Integer type, @PathVariable("projectId") Long projectId) {
        AdminRoleTypeEnum roleTypeEnum = AdminRoleTypeEnum.parse(type);
        List<AdminRole> roleByType = adminRoleService.getProjectRoleByType(roleTypeEnum, projectId);
        return Result.ok(roleByType);
    }


    @PostMapping("/queryRoleByRoleTypeAndUserId")
    @ApiExplain("项目管理:查询当前用户在某个模块下的角色")
    public Result<List<AdminRole>> queryRoleByRoleTypeAndUserId(@RequestParam("type") Integer type) {
        List<AdminRole> recordList = adminRoleService.queryRoleByRoleTypeAndUserId(type);
        return Result.ok(recordList);
    }


    @PostMapping("/queryRoleListByUserId")
    @ApiOperation("通过用户id查询角色")
    public Result<List<AdminRole>> queryRoleListByUserId(@RequestBody List<Long> userIds) {
        return Result.ok(adminRoleService.queryRoleListByUserId(userIds));
    }

    @PostMapping("/roles/users")
    @ApiOperation("获取用户的角色")
    public Result<Map<Long, List<AdminRole>>> getByUserIds(@RequestBody List<Long> userIds) {
        return Result.ok(adminRoleService.getByUserIds(userIds));
    }

    @PostMapping("/queryDataType")
    @ApiExplain("查询数据权限")
    public Result<Integer> queryDataType(@RequestParam("userId") Long userId, @RequestParam("menuId") Long menuId) {
        Integer dataType = adminRoleService.queryDataType(userId, menuId);
        return Result.ok(dataType);
    }

    @PostMapping("/queryCustomDeptId")
    @ApiExplain("查询自定义数据权限部门")
    public Result<List<Long>> queryCustomDeptId(@RequestParam("userId") Long userId, @RequestParam("menuId") Long menuId) {
        List<Long> deptIdList = adminRoleService.queryCustomDeptId(userId, menuId);
        return Result.ok(deptIdList);
    }

    @PostMapping("/queryUserByAuth")
    @ApiExplain("查询数据权限")
    public Result<Collection<Long>> queryUserByAuth(@RequestParam("userId") Long userId, @RequestParam("menuId") Long menuId) {
        Collection<Long> longs = adminRoleService.queryUserByAuth(userId, menuId);
        return Result.ok(longs);
    }

    @PostMapping("/add")
    @ApiOperation("添加角色")
    @OperateLog(apply = ApplyEnum.ROLE_PERMISSION_MANAGEMENT, object = OperateObjectEnum.EMPLOYEE_DEPARTMENT_MANAGEMENT, behavior = BehaviorEnum.SAVE, type = OperateTypeEnum.SETTING)
    public Result add(@RequestBody AdminRole adminRole) {
        OperationLog operationLog = adminRoleService.add(adminRole);
        return OperationResult.ok(ListUtil.toList(operationLog));
    }

    @PostMapping("/addProjectRole")
    @ApiOperation("添加自定义项目角色和权限")
    @OperateLog(apply = ApplyEnum.PROJECT_MANAGEMENT, object = OperateObjectEnum.CUSTOM_ROLE, behavior = BehaviorEnum.SAVE, type = OperateTypeEnum.SETTING)
    public Result addProjectRole(@RequestBody AdminRole adminRole) {
        JSONObject data = adminRoleService.addProjectRole(adminRole);
        Object role = data.get("role");
        OperationLog operationLog = (OperationLog) data.get("operationLog");
        return OperationResult.ok(role, ListUtil.toList(operationLog));
    }

    @PostMapping("/update")
    @ApiOperation("修改角色")
    @OperateLog(apply = ApplyEnum.ROLE_PERMISSION_MANAGEMENT, behavior = BehaviorEnum.UPDATE, type = OperateTypeEnum.SETTING)
    public Result update(@RequestBody AdminRole adminRole) {
        OperationLog operationLog = adminRoleService.add(adminRole);
        return OperationResult.ok(ListUtil.toList(operationLog));

    }

    @PostMapping("/delete")
    @ApiOperation("删除角色")
    @OperateLog(behavior = BehaviorEnum.DELETE, type = OperateTypeEnum.SETTING)
    public Result delete(@RequestParam("roleId") Long roleId) {
        OperationLog operationLog = adminRoleService.delete(roleId);
        return OperationResult.ok(ListUtil.toList(operationLog));
    }

    @PostMapping("/copy")
    @ApiOperation("复制角色")
    @OperateLog(apply = ApplyEnum.ROLE_PERMISSION_MANAGEMENT, behavior = BehaviorEnum.COPY, type = OperateTypeEnum.SETTING)
    public Result copy(@RequestParam("roleId") Long roleId) {
        OperationLog operationLog = adminRoleService.copy(roleId);
        return OperationResult.ok(ListUtil.toList(operationLog));
    }

    @PostMapping("/relatedDeptUser")
    @ApiOperation("角色关联员工部门")
    @OperateLog(apply = ApplyEnum.SYSTEM_SETTING, object = OperateObjectEnum.EMPLOYEE_DEPARTMENT_MANAGEMENT, behavior = BehaviorEnum.EDIT_ROLE, type = OperateTypeEnum.SETTING)
    public Result relatedDeptUser(@RequestBody AdminRoleBO adminRoleBO) {
        List<OperationLog> operationLogList = adminRoleService.relatedDeptUser(adminRoleBO.getUserIds(), adminRoleBO.getDeptIds(), adminRoleBO.getRoleIds());
        return OperationResult.ok(operationLogList);
    }

    @PostMapping("/relatedUser")
    @ApiOperation("角色关联员工")
    @OperateLog(behavior = BehaviorEnum.UPDATE, type = OperateTypeEnum.SETTING)
    public Result relatedUser(@RequestBody AdminRoleBO adminRoleBO) {
        List<OperationLog> operationLogList = adminRoleService.relatedUser(adminRoleBO.getUserIds(), adminRoleBO.getRoleIds());
        return OperationResult.ok(operationLogList);
    }


    @PostMapping("/addRelatedDept")
    @ApiOperation("新增角色关联部门")
    public Result addRelatedDept(@RequestBody AdminRoleBO adminRoleBO) {
        adminRoleService.addRelatedDept(adminRoleBO.getDeptIds(), adminRoleBO.getRoleIds());
        return Result.ok();
    }

    @PostMapping("/updateRelatedDept")
    @ApiOperation("修改角色关联部门")
    public Result updateRelatedDept(@RequestBody AdminRoleBO adminRoleBO) {
        adminRoleService.updateRelatedDept(adminRoleBO.getDeptIds(), adminRoleBO.getRoleIds());
        return Result.ok();
    }


    @PostMapping("/accountUserRole")
    @ApiOperation("账套授权角色关联员工")
    public Result accountUserRole(@RequestBody AdminUserRoleBO userRoleBO) {
        adminRoleService.accountUserRole(userRoleBO);
        return Result.ok();
    }

    @PostMapping("/unbindingUser")
    @ApiOperation("取消角色关联员工")
    @OperateLog(behavior = BehaviorEnum.UPDATE, type = OperateTypeEnum.SETTING)
    public Result unbindingUser(@RequestParam("userId") Long userId, @RequestParam("roleId") Long roleId) {
        OperationLog operationLog = adminRoleService.unbindingUser(userId, roleId);
        return OperationResult.ok(ListUtil.toList(operationLog));
    }

    @PostMapping("/unbindingDept")
    @ApiOperation("取消角色关联部门")
    public Result unbindingDept(@RequestParam("deptId") Long deptId, @RequestParam("roleId") Long roleId) {
        adminRoleService.unbindingDept(deptId, roleId);
        return Result.ok();
    }


    @PostMapping("/updateRoleMenu")
    @ApiOperation("保存角色菜单关系")
    @OperateLog(behavior = BehaviorEnum.UPDATE, type = OperateTypeEnum.SETTING)
    public Result updateRoleMenu(@RequestBody AdminRole adminRole) {
        OperationLog operationLog = adminRoleService.updateRoleMenu(adminRole);
        return OperationResult.ok(ListUtil.toList(operationLog));
    }

    @PostMapping("/updateAuthRole/{roleId}")
    @ApiOperation("保存角色与能看到角色的关系关系")
    public Result updateAuthRole(@PathVariable("roleId") Long roleId, @RequestBody List<Long> authRoleIds) {
        adminRoleAuthService.saveRoleAuth(roleId, authRoleIds);
        return Result.ok();
    }

    @PostMapping("/queryAuthRole/{roleId}")
    @ApiOperation("查询角色与能看到角色的关系关系")
    public Result<List<Long>> queryAuthRole(@PathVariable("roleId") Long roleId) {
        List<Long> roleIdList = adminRoleAuthService.queryByRoleId(roleId);
        return Result.ok(roleIdList);
    }

    @PostMapping(value = "/queryWorkRole")
    @ApiExplain("查询项目管理角色")
    public Result<Long> queryWorkRole(@RequestParam("label") Integer label) {
        Long role = adminRoleService.queryWorkRole(label);
        return Result.ok(role);
    }

    @PostMapping(value = "/setWorkRole")
    @ApiExplain("设置项目管理角色")
    public Result setWorkRole(@RequestBody JSONObject object) {
        adminRoleService.setWorkRole(object);
        return Result.ok();
    }

    @PostMapping(value = "/deleteWorkRole")
    @ApiExplain("删除项目管理角色")
    public Result deleteWorkRole(@RequestParam("roleId") Long roleId) {
        adminRoleService.deleteWorkRole(roleId);
        return Result.ok();
    }

    @PostMapping(value = "/queryWorkRoleList")
    @ApiOperation("查询项目管理角色列表")
    public Result<List<AdminRole>> queryWorkRoleList() {
        List<AdminRole> adminRoles = adminRoleService.queryRoleList();
        return Result.ok(adminRoles);
    }

    @PostMapping(value = "/queryDefaultRole")
    @ApiOperation("查询默认角色列表")
    public Result<AdminRole> queryDefaultRole() {
        AdminRole adminRoles = adminRoleService.queryDefaultRole();
        return Result.ok(adminRoles);
    }

    @PostMapping("/queryUserIdByRoleId")
    @ApiExplain("根据角色ID查询用户列表")
    public Result<List<Long>> queryUserIdByRoleId(@RequestParam("roleId") Long roleId) {
        List<Long> userIds = adminRoleService.queryUserIdByRoleId(CollectionUtil.toList(roleId));
        return Result.ok(userIds);
    }


    @PostMapping("/queryUserIdByRoleIds")
    @ApiExplain("根据角色IDs查询用户列表")
    public Result<List<Long>> queryUserIdByRoleIds(@RequestParam("roleIds") List<Long> roleIds) {
        List<Long> userIds = adminRoleService.queryUserIdByRoleId(roleIds);
        return Result.ok(userIds);
    }

    @PostMapping("/listByRoleId")
    @ApiOperation("角色查询")
    public Result<List<Map<String, Object>>> updateAuthRole(@RequestBody List<Long> roleIds) {
        List<Map<String, Object>> result = adminRoleService.listByRoleId(roleIds);
        return Result.ok(result);
    }

    @PostMapping(value = "/delUserRole")
    @ApiExplain("账套员工角色单条删除")
    public Result delUserRole(@RequestParam("userId") Long userId) {
        adminRoleService.delUserRole(userId);
        return Result.ok();
    }

    @PostMapping(value = "/queryRoleByRoleId")
    @ApiExplain("查询角色信息")
    public Result<AdminRole> queryRoleByRoleId(@RequestParam("roleId") Long roleId) {
        return Result.ok(adminRoleService.getById(roleId));
    }


    @PostMapping(value = "/queryProjectRoleByTypes")
    @ApiExplain("根据项目类型查询项目管理角色")
    public Result<List<com.kakarote.core.feign.admin.entity.AdminRole>> queryProjectRoleByTypes(@RequestParam("types") List<Integer> types) {
        List<com.kakarote.core.feign.admin.entity.AdminRole> adminRoles = new ArrayList<>();
        List<AdminRole> roles = adminRoleService.lambdaQuery().eq(AdminRole::getRoleType, 8).in(AdminRole::getLabel, types).list();
        if (CollectionUtil.isNotEmpty(roles)) {
            roles.stream().forEach(r -> {
                com.kakarote.core.feign.admin.entity.AdminRole adminRole = new com.kakarote.core.feign.admin.entity.AdminRole();
                BeanUtil.copyProperties(r, adminRole);
                adminRoles.add(adminRole);
            });
        }
        return Result.ok(adminRoles);
    }

    @PostMapping("/wpAuth")
    @ApiOperation("获取WP管理角色权限")
    public Result<JSONObject> wpAuth() {
        JSONObject object = adminRoleService.wpAuth();
        return Result.ok(object);
    }


    @PostMapping("/queryUserCustomDeptId")
    @ApiOperation("查询人力资源自定义部门id")
    public Result<Set<Long>> queryUserCustomDeptId(@RequestParam("userId") Long userId, @RequestParam("menuId") Long menuId){
        return Result.ok(adminRoleService.queryUserCustomDeptId(userId,menuId));
    }

    /**
     * 查询数据权限集合
     *
     * @param userId 用户ID
     * @param menuId 菜单ID
     * @return 权限
     */
    @PostMapping(value = "/queryDataTypeList")
    public Result<List<Integer>> queryDataTypeList(@RequestParam("userId") Long userId, @RequestParam("menuId") Long menuId){
        return Result.ok(adminRoleService.queryDataTypeList(userId, menuId));
    }
}

